﻿using System;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using KryptecizerBase;
using KryptecizerBase.EventArguments;
using System.Collections;
using Kryptonalysis.EventArguments;
using System.Threading;

namespace Kryptecizer
{
    public partial class kr_MainForm : XtraForm
    {
        private bool encryptetTextChangeing = false;
        private bool decryptedTextChangeing = false;

        private void KryptObject_DecryptedTextChanged(TextChangedEventArgs arg)
        {
            progressBarControl1.Position = 100;
            decryptedTextMemo.Text = arg.Text;
        }

        private void KryptObject_EncryptedTextChanged(TextChangedEventArgs arg)
        {
            progressBarControl1.Position = 100;
            encryptedTextMemo.Text = arg.Text;
        }

        private void KryptObject_WorkPercentProcessed(int percentDone)
        {
            progressBarControl1.Position = percentDone;
        }

        public kr_MainForm()
        {
            InitializeComponent();

            kr_Controller.Instance.KryptObject.WorkPercentProcessed += KryptObject_WorkPercentProcessed;
            kr_Controller.Instance.KryptObject.DecryptedTextChanged += KryptObject_DecryptedTextChanged;
            kr_Controller.Instance.KryptObject.EncryptedTextChanged += KryptObject_EncryptedTextChanged;
        }

        private void ExitItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            Application.Exit();
        }

        private void AboutItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new kr_AboutBox().ShowDialog();
        }

        private void openDecryptedFileItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                ofd.Filter = "TextFiles (.txt)|*.txt";
                ofd.Multiselect = false;
                DialogResult dr = ofd.ShowDialog();
                if (dr == DialogResult.OK)
                    kr_Controller.Instance.readTextFile(Kryptstate.DECRYPTED, ofd.FileName);
            }
        }

        private void openEncryptedFileItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                ofd.Filter = "TextFiles (.txt)|*.txt";
                ofd.Multiselect = false;
                DialogResult dr = ofd.ShowDialog();
                if (dr == DialogResult.OK)
                    kr_Controller.Instance.readTextFile(Kryptstate.ENCRYPTED, ofd.FileName);
            }
        }

        private void saveDecryptedFileItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                sfd.Filter = "TextFiles (.txt)|*.txt";
                DialogResult dr = sfd.ShowDialog();
                if (dr == DialogResult.OK)
                    kr_Controller.Instance.saveTextToFile(sfd.FileName, decryptedTextMemo.Text);
            }
        }

        private void saveEncryptedFileItem_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                sfd.Filter = "TextFiles (.txt)|*.txt";
                DialogResult dr = sfd.ShowDialog();
                if (dr == DialogResult.OK)
                    kr_Controller.Instance.saveTextToFile(sfd.FileName, encryptedTextMemo.Text);
            }
        }

        private void hidePasswordCheck_CheckedChanged(object sender, EventArgs e)
        {
            if (hidePasswordCheck.Checked)
                passwordEdit.Properties.PasswordChar = '*';
            else
                passwordEdit.Properties.PasswordChar = new Char();
        }

        private void proceedBtn_Click(object sender, EventArgs e)
        {
            progressBarControl1.Position = 0;
            if (!passwordEdit.Text.Equals(""))
                switch (cryptTypeEdit.SelectedText)
                {
                    case "Caesar decrypt":
                        {
                            Thread decryptThread = new Thread(new ThreadStart(decryptCaesar));
                            decryptThread.Start();
                        }
                        break;
                    case "Caesar encrypt":
                        {
                            Thread decryptThread = new Thread(new ThreadStart(encryptCaesar));
                            decryptThread.Start();
                        }
                        break;
                    case "Vigenere decrypt":
                        {
                            Thread decryptThread = new Thread(new ThreadStart(decryptCaesar));
                            decryptThread.Start();
                        }
                        break;
                    case "Vigenere encrypt":
                        {
                            Thread decryptThread = new Thread(new ThreadStart(encryptVigenere));
                            decryptThread.Start();
                        }
                        break;
                    default:
                        MessageBox.Show("Please choose a de-/ encrypt type", "please make a selection", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                }
            else
                switch (cryptTypeEdit.SelectedText)
                {
                    case "Caesar decrypt":
                        {
                            Thread analysisThread = new Thread(new ThreadStart(analyzeCaesar));
                            analysisThread.Start();
                        }
                        break;
                    case "Vigenere decrypt":
                        {
                            Thread analysisThread = new Thread(new ThreadStart(analyzeVigenere));
                            analysisThread.Start();
                        }
                        break;
                    default:
                        MessageBox.Show("Please choose a de-/ encrypt type", "please make a selection", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                }
        }

        private void decryptedTextMemo_EditValueChanged(object sender, EventArgs e)
        {
            if ((!encryptetTextChangeing))
            {
                decryptedTextChangeing = true;
                encryptedTextMemo.Text = "";
                kr_Controller.Instance.KryptObject.kryptoTextDecrypted.Fill(decryptedTextMemo.Text);
                cryptTypeEdit.Properties.Items.Clear();
                cryptTypeEdit.Properties.Items.Add("Caesar encrypt");
                cryptTypeEdit.Properties.Items.Add("Vigenere encrypt");
                cryptTypeEdit.EditValue = null;
                decryptedTextChangeing = false;
            }
        }

        private void encryptedTextMemo_EditValueChanged(object sender, EventArgs e)
        {
            if (!decryptedTextChangeing)
            {
                encryptetTextChangeing = true;
                decryptedTextMemo.Text = "";
                kr_Controller.Instance.KryptObject.kryptoTextEncrypted.Fill(encryptedTextMemo.Text);
                cryptTypeEdit.Properties.Items.Clear();
                cryptTypeEdit.Properties.Items.Add("Caesar decrypt");
                cryptTypeEdit.Properties.Items.Add("Vigenere decrypt");
                cryptTypeEdit.EditValue = null;
                encryptetTextChangeing = false;
            }
        }

        private void decryptCaesar()
        {
            kr_Controller.Instance.DecryptCaesar(passwordEdit.Text, actionProcessing);
        }

        private void encryptCaesar()
        {
            kr_Controller.Instance.EncryptCaesar(passwordEdit.Text, actionProcessing);
        }

        private void decryptVigenere()
        {
            kr_Controller.Instance.DecryptVigenere(passwordEdit.Text, actionProcessing);
        }

        private void encryptVigenere()
        {

            kr_Controller.Instance.EncryptVigenere(passwordEdit.Text, actionProcessing);
        }

        private void analyzeCaesar()
        {
            kr_Controller.Instance.AnalyzeCaesar(analysisEnded, actionProcessing, actionProcessing);
        }

        private void analyzeVigenere()
        {
            kr_Controller.Instance.AnalyzeVigenere(analysisEnded, actionProcessing, actionProcessing);
        }

        private void actionProcessing(int percentDone)
        {
            if (progressBarControl1.InvokeRequired)
                progressBarControl1.Invoke(new MethodInvoker(delegate { setProgress(percentDone); }));
            else
                setProgress(percentDone);
        }

        private void analysisEnded(Kryptonalysis.EventArguments.AnalysisEndedEventArgs args)
        {
            if (!args.PW.Equals(""))
                if (passwordEdit.InvokeRequired)
                    passwordEdit.Invoke(new MethodInvoker(delegate { setPasswordText(args.PW); }));
                else
                    setPasswordText(args.PW);

            if (args.Stats != null)
            {
                DialogResult dr = MessageBox.Show("Analysis ended", "Statistics available. Show statistics?", 
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                    new StatisticsForm().Show(args.Stats);
            }
        }

        private void setProgress(int percentDone)
        {
            progressBarControl1.Position = percentDone;
        }

        private void setPasswordText(String pw)
        {
            passwordEdit.Text = pw;
        }
    }
}
